/*
 * Copyright (c) 2008, Takashi Ito
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the authors nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "tansu_internal.h"
#include <wx/wx.h>
#include <wx/image.h>

#ifndef UPNPFRAME_H
#define UPNPFRAME_H

// begin wxGlade: ::dependencies
#include <wx/splitter.h>
#include <wx/treectrl.h>
#include <wx/tglbtn.h>
#include <wx/listctrl.h>
#include <wx/notebook.h>
// end wxGlade

// begin wxGlade: ::extracode
enum {
    ID_SEARCH_TARGET = 100,
    ID_MSEARCH_BUTTON,
    ID_FILTER,
    ID_START_BUTTON,
    ID_TREE_CTRL,
    ID_COLLAPSE_BUTTON,
    ID_EXPAND_BUTTON,
    ID_CLEAR_BUTTON,
    ID_ACTION_LIST_CTRL,
    ID_EXEC_BUTTON,
    ID_EXEC_OPTION_BUTTON,
    ID_STATE_VARIABLE_LIST_CTRL,
    ID_SUBSCRIBE_BUTTON,
};
// end wxGlade

#include <sys/queue.h>
#include <netinet/in.h>
#include "event.h"
#include "evhttp.h"
#include "tdom.h"
#include "tdom_writer.h"
#include "tansu_internal.h"
#include "tansu_util.h"
#include "tansu_socket.h"
#include "tansu_ssdp.h"
#include "tansu_http.h"
#include "tansu_upnp.h"
#include "tansu_upnp_cp.h"
#include "UpnpTreeItemData.h"

#ifndef tdom_get_elem_value
#define tdom_get_elem_value(parent, name, ns, index) \
    tdom_get_value(tdom_get_elem((parent), (name), (ns), (index)))
#endif


#define KIND_ALL        (~0)
#define KIND_MSEARCH    (1<<0)
#define KIND_NOTIFY     (1<<1)

enum UpnpPanelId {
    PANEL_NONE,
    PANEL_DEVICE,
    PANEL_SERVICE,
};

class UpnpFrame: public wxFrame {
public:
    // begin wxGlade: UpnpFrame::ids
    // end wxGlade

    UpnpFrame(struct event_base* evbase,
              wxWindow* parent,
              int id,
              const wxString& title,
              const wxPoint& pos=wxDefaultPosition,
              const wxSize& size=wxDefaultSize,
              long style=wxDEFAULT_FRAME_STYLE);
    virtual ~UpnpFrame();

private:
    // begin wxGlade: UpnpFrame::methods
    void set_properties();
    void do_layout();
    // end wxGlade

protected:
    // begin wxGlade: UpnpFrame::attributes
    wxStatusBar* frame_1_statusbar;
    wxComboBox* combo_box_st;
    wxButton* button_search;
    wxComboBox* combo_box_filter;
    wxToggleButton* button_start;
    wxTreeCtrl* tree_ctrl_1;
    wxListCtrl* list_ctrl_ssdp;
    wxNotebook* notebook_tree;
    wxButton* button_collapse;
    wxButton* button_expand;
    wxButton* button_clear;
    wxPanel* panel_1;
    wxStaticText* label_15;
    wxTextCtrl* text_ctrl_location;
    wxStaticText* label_1;
    wxTextCtrl* text_ctrl_device_major;
    wxStaticText* label_2;
    wxTextCtrl* text_ctrl_device_minor;
    wxStaticText* label_3;
    wxTextCtrl* text_ctrl_url_base;
    wxListCtrl* list_ctrl_device;
    wxStaticText* label_4;
    wxListCtrl* list_ctrl_icon;
    wxStaticText* label_5;
    wxListCtrl* list_ctrl_service;
    wxStaticText* label_6;
    wxTextCtrl* text_ctrl_presentation;
    wxPanel* notebook_1_pane_1;
    wxTextCtrl* text_ctrl_dd;
    wxPanel* notebook_1_pane_2;
    wxNotebook* notebook_1;
    wxStaticText* label_7;
    wxTextCtrl* text_ctrl_service_major;
    wxStaticText* label_8;
    wxTextCtrl* text_ctrl_service_minor;
    wxListCtrl* list_ctrl_action;
    wxButton* button_exec;
    wxButton* button_exec_option;
    wxStaticText* label_9;
    wxListCtrl* list_ctrl_argument;
    wxPanel* notebook_2_pane_1;
    wxListCtrl* list_ctrl_state_variable;
    wxButton* button_subscribe;
    wxStaticText* label_10;
    wxListCtrl* list_ctrl_allowed_value;
    wxStaticText* label_11;
    wxTextCtrl* text_ctrl_minimum;
    wxStaticText* label_12;
    wxTextCtrl* text_ctrl_maximum;
    wxStaticText* label_13;
    wxTextCtrl* text_ctrl_step;
    wxPanel* notebook_2_pane_2;
    wxTextCtrl* text_ctrl_scpd;
    wxPanel* notebook_2_pane_3;
    wxNotebook* notebook_2;
    wxStaticText* label_14;
    wxPanel* panel_3;
    wxPanel* panel_2;
    wxSplitterWindow* window_1;
    // end wxGlade

    DECLARE_EVENT_TABLE();

    wxSizer *sizer;
    struct tansu_ssdp_server *server;
    struct tansu_ssdp_listener *listener;
    struct tansu_ssdp_request *req;
    int num_responses;
    int num_valid;
    wxString filter;
    struct tansu_cp_discoveries discoveries;
    wxTreeItemId root;
    struct event_base* evbase;

public:
    virtual void OnSearchTargetTextEnter(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnMSearchButton(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnFilterTextEnter(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnFilterComboBox(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnToggleButton(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnCollapseButton(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnExpandButton(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnClearButton(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnActionDeselected(wxListEvent &event); // wxGlade: <event_handler>
    virtual void OnActionSelected(wxListEvent &event); // wxGlade: <event_handler>
    virtual void OnActionExecButton(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnStateVariableDeselected(wxListEvent &event); // wxGlade: <event_handler>
    virtual void OnStateVariableSelected(wxListEvent &event); // wxGlade: <event_handler>
    virtual void OnSubscribeButton(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnActionExecOptionButton(wxCommandEvent &event); // wxGlade: <event_handler>
    virtual void OnTreeSelChanged(wxTreeEvent &event); // wxGlade: <event_handler>

    void HandlePacket(const struct tansu_ssdp_packet *packet);
    void ExecuteMSearch();
    void MSearchFinished(struct tansu_ssdp_request *req);
    void DDHandler(struct evhttp_request *req, struct tansu_cp_discovery *discovery);
    void SCPDHandler(struct evhttp_request *req,
                     struct tansu_cp_discovery *discovery,
                     const char *sid);
    wxTreeItemId CreateTreeNode(const wxTreeItemId parent, const wxString& text);
    wxTreeItemId GetTreeNode(const wxTreeItemId parent,
                             const wxString& text,
                             bool create = false);
    wxTreeItemId FindDevice(const wxString *type, const wxString& udn);
    wxTreeItemId GetDeviceTreeNode(const wxTreeItemId parent, const wxString& udn);
    wxTreeItemId FindTreeItem(const wxTreeItemId parent, const wxString& text);
    void SetTreeItem(struct tansu_cp_discovery *discovery,
                     DeviceTreeItemData *data);
    void SetDeviceInfo(DeviceTreeItemData *data);
    void SetServiceInfo(ServiceTreeItemData *data);
    void SetDeviceParam(struct tdom_elem *elem);
    void SetIconList(struct tdom_elem *elem);
    void SetServiceList(struct tdom_elem *elem);
    void UpdateServices(wxTreeItemId& id,
                        DeviceTreeItemData *data,
                        struct tansu_cp_discovery *discovery);
    void SetActivePanel(enum UpnpPanelId id);
    void UpdateDiscovery(struct tansu_cp_discovery *discovery,
                         enum tansu_ssdp_nts nts,
                         const struct tansu_ssdp_packet *packet);
    void UpdateDiscoveryList(long n, struct tansu_cp_discovery *discovery);
    void UpdateTypeNodeText(wxTreeItemId& id);
    void UpdateDevice(enum tansu_ssdp_nts nts,
                      const struct tansu_ssdp_packet *packet);

    const struct tansu_cp_device *GetCurrentDevice();
    const struct tansu_cp_service *GetCurrentService();

    static wxString GetTime(const time_t *t);
    static int GetSelectedListIndex(const wxListCtrl& listCtrl);

}; // wxGlade: end class


#endif // UPNPFRAME_H
